#include "crane_evb_keypad.h"

#if USE_CRANE_EVB_KEYPAD

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include "crane_keypadc.h"
#include "lvgl/src/lv_core/lv_group.h"

static uint32_t last_key;
static lv_indev_state_t state;
static keypad_cb_t usr_cb = 0;

static void keypad_handler(uint32_t key_event, uint32_t key_value)
{
    switch (key_event) {
        case KEY_DOWN:                              /*Button press*/
            last_key = key_value;            /*Save the pressed key*/
            state = LV_INDEV_STATE_PR;          /*Save the key is pressed now*/
            break;
        case KEY_UP:                                /*Button release*/
            state = LV_INDEV_STATE_REL;         /*Save the key is released but keep the last key*/
            break;
        default:
            break;
    }

    extern void normal_key_wakeup(uint32_t key);
    normal_key_wakeup(key_value);
    return;
}

static uint32_t keycode_map(uint32_t crane_key)
{
    switch (crane_key) {
        case KP_RT:
            return LV_KEY_RIGHT;

        case KP_LT:
            return LV_KEY_LEFT;

        case KP_UP:
            return LV_KEY_UP;

        case KP_DW:
            return LV_KEY_DOWN;

        case KP_OK:
            return LV_KEY_ENTER;

        case KP_CALL:
            return LV_KEY_DIAL;

        case KP_PWR:
            return LV_KEY_END;

        case KP_SR:
            return LV_KEY_BACKSPACE;

        case KP_SL:
            return LV_KEY_SL;

        default:
            return crane_key;
    }
}

bool keypad_crane_evb_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
{
    (void) indev_drv;      /*Unused*/

    struct keypad_param val;
    val.key_event = KEY_EVENT_NONE;
    val.data.state = LV_INDEV_STATE_REL;

#if USE_ONKEY_HISR
    handle_onkey(&val);
#endif
    if((val.key_event == KEY_EVENT_NONE) && (val.data.state == LV_INDEV_STATE_REL)) {
        val.data.state = state;
        val.data.key = keycode_map(last_key);

        if (usr_cb && (KEY_HANDLE_OVER == usr_cb(&val))) {
            return false;
        }

        data->state = val.data.state;
        data->key = val.data.key;
    } else {
        if (usr_cb && (KEY_HANDLE_OVER == usr_cb(&val))) {
            return false;
        }
        *data = val.data;
    }
    return false;
}

void keypad_crane_evb_init(keypad_cb_t cb)
{
    usr_cb = cb;

#if USE_ONKEY_HISR
    onkey_init();
    lv_pm_info_t pm_info;
    pm_info.suspend = onkey_suspend;
    pm_info.resume = onkey_resume;
    pm_info.data = NULL;
    pm_info.part = LV_PM_PART_MISC;
    lv_pm_register(&pm_info);
#endif

    crane_keypadc_init();
    crane_keypadc_set_handler((keypad_handler_t)keypad_handler);
}

#endif /* USE_CRANE_EVB_KEYPAD */
